﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.IO;

namespace Module_Debug.Others.control_tools_lir.control_lir_com
{
    [StructLayout(LayoutKind.Sequential)]
    public struct OutParam
    {

        public int iLength;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 25)]

        public double[] data;

    }

    public struct InParam
    {
        public string str_id;
        public float target_lum;
        public float delta;
        public int scale_lum;
        public int long_package;
        public int gamma_node_cnt;
        public int check_type;
        public int ratio_base;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public int[] rtn_value;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
        public int[] gamma_node;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
        public int[] rstring_r;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
        public int[] rstring_g;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
        public int[] rstring_b;

        public float top_compensate_ratio;
        public float bottom_compensate_ratio;
        public float uniformity1;
        public float uniformity2;

    }
    public struct OutResult
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
        public byte[] str_return_code;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8192)]
        public byte[] str_cmd_int;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8192)]
        public byte[] str_cmd_result;
        public double d_persent_lum;
    }
    public static class com_function_lir
    {
        [DllImport("VisionoxTools_Plug.dll", EntryPoint = "IDI_VISIONOX_LIR_INIT")]
        public extern static int api_lir_init(string str);

        [DllImport("VisionoxTools_Plug.dll", EntryPoint = "IDI_VISIONOX_LIR_SET")]
        public extern static int api_set_param(InParam param, out OutParam out_param);

        [DllImport("VisionoxTools_Plug.dll", EntryPoint = "IDI_VISIONOX_LIR_GRN")]
        public extern static int api_run_function(out OutResult out_param);

        [DllImport("VisionoxTools_Plug.dll", EntryPoint = "IDI_VISIONOX_LIR_RELEASE")]
        public extern static int api_lir_release();
    }
    static class com_fun_hs
    {
        [DllImport("VisionoxTools_Plug.dll", EntryPoint = "IDI_VISIONOX_LIR_T_FUNCTION")]
        public extern static int api_lir_hs_run();

        [DllImport("VisionoxTools_Plug.dll", EntryPoint = "IDI_VISIONOX_LIR_T_RELEASE")]
        public extern static int api_lir_hs_release();
    }

    static class com_fun_nova
    {
        [DllImport("VDCTuningDll.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void RunCommand(string command);

        [DllImport("VDCTuningDll.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int UniformityTuning_ReadMcr(string dir);

        [DllImport("VDCTuningDll.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int UniformityTuning_RunCoroutine(int ind, string dir, ref double uniformity);

        [DllImport("VDCTuningDll.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "UniformityTuning_CalculateCSVUniformity")]
        private static extern int _CalculateCSVUniformity(string dir, ref double uniformity, double[] nine_points);

        [DllImport("VDCTuningDll.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "UniformityTuning_CalculateUniformity")]
        private static extern int _CalculateUniformity(double[] data, int W, int H, ref double uniformity, double[] nine_points);

        [DllImport("VDCTuningDll.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int UniformityTuning_RunRestartCoroutine(int ind, string dir, ref double uniformity);

        public static bool run_nova_lir(int index,string str_path,out string str_code,out double d_uniformity)
        {
            str_code = "";
            d_uniformity = 0.0;
            //int error_code = 0;
            //string str_mcrfname = "";
            //string str_csvfname = "";
            double uniformity = 0.0;

            string str_lua_lib = str_path.Replace("\\", "/");
            string str_dir = str_lua_lib + "\\" + "output_uniformity" + "\\";
            string str_out_path = str_lua_lib + "\\" + "output_uniformity";
            if (!Directory.Exists(str_out_path))
            {
                try
                {
                    Directory.CreateDirectory(str_out_path);
                }
                catch (Exception e)
                {
                    throw e;
                }
            }
            str_dir = str_dir.Replace("\\", "/");

            string str_set_path = string.Format("VDCLibDir = '{0}/VDCTuningLib'", str_lua_lib);
            string str_set_main = string.Format("dofile('{0}/VDCTuningLib/main.lua')", str_lua_lib);

            RunCommand(str_set_path);
            RunCommand(str_set_main);

            int ires = UniformityTuning_RunRestartCoroutine(index, str_dir, ref uniformity);

            if (ires < 0) // Error occurred
            {
                return false;
            }
            if(ires == 0)
            {
                d_uniformity = uniformity;
                string str_mrc_name = str_dir + "VDCUniformity.mcr";
                str_mrc_name = str_mrc_name.Replace("/", "\\");
                StreamReader sR = File.OpenText(str_mrc_name);
                string nextLine;
                string strText = "";
                while ((nextLine = sR.ReadLine()) != null)
                {
                    strText = strText + nextLine + "\r\n";
                    if (sR.EndOfStream)
                    {
                        strText = strText + nextLine;
                    }
                }
                sR.Close();
                str_code = strText;
            }
            else
            {
                string str_mrc_name = string.Format("{0}/VDCUniformity_{1}.mcr", str_dir, index);
                string str_data_name = string.Format("{0}/VDCUniformity_{1}.csv", str_dir, index);
                str_mrc_name = str_mrc_name.Replace("/", "\\");
                //
                StreamReader sR = File.OpenText(str_mrc_name);
                string nextLine;
                string strText = "";
                while ((nextLine = sR.ReadLine()) != null)
                {
                    strText = strText + nextLine + "\r\n";
                    if (sR.EndOfStream)
                    {
                        strText = strText + nextLine;
                    }
                }
                sR.Close();
                str_code = strText;
            }
            return true;
        }
        public static double[] CalculateCSVUniformity(int index,string csvfname, ref double uniformity)
        {
            double[] Lv = { 0 };
            //_____3*3//3*5//3*15//9*15_____//
            if (index == 0)
            {
                Lv = new double[9];
                int error_code = _CalculateCSVUniformity(csvfname, ref uniformity, Lv);
                if (error_code != 0) return null;
                return Lv;
            }
            else if(index == 1)
            {
                Lv = new double[9*15];
                int error_code = _CalculateCSVUniformity(csvfname, ref uniformity, Lv);
                if (error_code != 0) return null;
                return Lv;
            }
            else if (index == 2)
            {
                Lv = new double[3 * 5];
                int error_code = _CalculateCSVUniformity(csvfname, ref uniformity, Lv);
                if (error_code != 0) return null;
                return Lv;
            }
            else if (index == 3)
            {
                Lv = new double[3 * 15];
                int error_code = _CalculateCSVUniformity(csvfname, ref uniformity, Lv);
                if (error_code != 0) return null;
                return Lv;
            }
            return Lv;
        }
    }
}
